package com.sjsu.aws.configurationMgmt;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import com.amazonaws.services.dynamodb.model.AttributeValue;
import com.amazonaws.services.dynamodb.model.ComparisonOperator;
import com.amazonaws.services.dynamodb.model.Condition;
import com.amazonaws.services.dynamodb.model.ScanResult;
import com.sjsu.aws.db.QueryCriteria;
import com.sjsu.aws.db.TableOperationImpl;
import com.sjsu.aws.db.TableRow;

/**
 * 
 * @author Pawar Deepali
 * 
 */
public class WatcherRegisterServiceImpl implements WatcherRegisterService {
	
	private final static Logger	LOG	= Logger.getLogger(WatcherRegisterServiceImpl.class);
	
	private TableOperationImpl	        tableOperationImpl;
	private TableRow	                tableRow;
	private QueryCriteria	            criteria;
	
	public WatcherRegisterServiceImpl() throws Exception {		
		this.tableOperationImpl = new TableOperationImpl();
		this.tableRow = new TableRow();
		this.criteria = new QueryCriteria();
		
	}
	
	@Override
	public void addWatcher(Watcher watcher) throws Exception {
		LOG.info("Adding Watcher for configuration");
		tableRow.setItem(createWatcherItem(watcher));
		tableOperationImpl.insertItem(
		        ConfigMgmtConstants.WATCHER_REGISTER_TABLE, tableRow);
	}
	
	@Override
	public void removeWatcher(Watcher watcher) throws Exception {
	}
	
	/**
	 * 
	 * @param watcher
	 * @return
	 * @throws Exception
	 */
	private Map<String, AttributeValue> createWatcherItem(Watcher watcher)
	        throws Exception {
		LOG.info("Creating Watcher Object");
		Map<String, AttributeValue> item = new HashMap<String, AttributeValue>();
		item.put(ConfigMgmtConstants.COLUMN_WATCHER_NAME, new AttributeValue(
		        watcher.getWatcherName()));
		item.put(ConfigMgmtConstants.COLUMN_WATCH_FLAG, new AttributeValue(
		        watcher.getWatchFlag()));
		return item;
	}
	
	@Override
	public List<Watcher> getRegisteredWatcherList() throws Exception {
		LOG.info("Getting list of Registered Watcher List");
		List<Watcher> watcherList = new ArrayList<Watcher>();
		ScanResult scanResult = tableOperationImpl
		        .queryTableWithNoCondition(ConfigMgmtConstants.WATCHER_REGISTER_TABLE);
		
		for (int i = 0; i < scanResult.getCount(); i++) {
			HashMap<String, AttributeValue> item = (HashMap<String, AttributeValue>) scanResult
			        .getItems().get(i);
			if (item.get(ConfigMgmtConstants.COLUMN_WATCH_FLAG).getS() != null) {
				Watcher newWatcher = new Watcher();
				newWatcher.setWatcherName(item.get(
				        ConfigMgmtConstants.COLUMN_WATCHER_NAME).getS());
				watcherList.add(newWatcher);
			}
		}
		return watcherList;
	}
	
	@Override
	public void updateWatchFlag(Watcher watcher) throws Exception {
		LOG.info("Update Watch Flag");
		tableRow.setUpdateKey(watcher.getWatcherName());
		tableRow.setUpdateColumnName(ConfigMgmtConstants.COLUMN_WATCH_FLAG);
		tableRow.setUpdateColumnValue(watcher.getWatchFlag());
		tableOperationImpl.UpdatePutItem(
		        ConfigMgmtConstants.WATCHER_REGISTER_TABLE, tableRow);
	}
	
	@Override
	public String getRegisteredWatcher(String watchId) throws Exception {
		LOG.info("Get Registered Watcher");
		HashMap<String, Condition> scanFilter = new HashMap<String, Condition>();
		Condition condition = new Condition().withComparisonOperator(
		        ComparisonOperator.EQ.toString()).withAttributeValueList(
		        new AttributeValue().withS(watchId));
		
		scanFilter.put(ConfigMgmtConstants.COLUMN_WATCHER_NAME, condition);
		
		ScanResult scanResult = tableOperationImpl.queryTable(
		        ConfigMgmtConstants.WATCHER_REGISTER_TABLE, criteria);
		
		for (int i = 0; i < scanResult.getCount(); i++) {
			HashMap<String, AttributeValue> item = (HashMap<String, AttributeValue>) scanResult
			        .getItems().get(i);
			if (item.get(ConfigMgmtConstants.COLUMN_WATCH_FLAG).getS() != null) {
				return item.get(ConfigMgmtConstants.COLUMN_WATCH_FLAG).getS();
			}
		}
		return null;
	}
}
